<template>
  <div>
    <el-dialog
      v-model="visible"
      :title="isAddStr === 'add' ? '新建' : '编辑'"
      class="add-vpc-access-dialog"
    >
      <el-form ref="formRef" :model="form" :rules="rules" class="m-auto mt-1">
        <el-form-item label="源地址" prop="s_addr">
          <el-input
            v-model="form.s_addr"
            placeholder="请按照0.0.0.0/0格式填写"
          />
        </el-form-item>
        <el-form-item label="目的地址" prop="d_addr">
          <el-input
            v-model="form.d_addr"
            placeholder="请按照0.0.0.0/0格式填写"
          />
        </el-form-item>
        <el-form-item label="协议" prop="protocol">
          <el-select
            filterable
            clearable
            v-model="form.protocol"
            class="w-full"
            @change="protocolChange"
          >
            <el-option label="all" value="all"></el-option>
            <el-option label="tcp" value="tcp"></el-option>
            <el-option label="udp" value="udp"></el-option>
            <el-option label="icmp" value="icmp"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item
          v-if="form.protocol === 'tcp' || form.protocol === 'udp'"
          prop="d_port"
          label="目的端口"
          class="tip-item"
        >
          <el-input v-model="form.d_port" class="d-port" />
          <span class="tip">(多个端口之间可用英文“,”分割)</span>
        </el-form-item>
        <el-form-item label="流入接口" prop="in_eth">
          <el-select filterable clearable v-model="form.in_eth" class="w-full">
            <el-option label="*" value="*"></el-option>
            <el-option
              v-for="item in portList"
              :label="item.name"
              :value="item.name"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="流出接口" prop="out_eth">
          <el-select filterable clearable v-model="form.out_eth" class="w-full">
            <el-option label="*" value="*"></el-option>
            <el-option
              v-for="item in portList"
              :label="item.name"
              :value="item.name"
            ></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="动作" prop="action">
          <el-radio-group v-model="form.action">
            <el-radio-button label="ACCEPT" value="ACCEPT" />
            <el-radio-button label="REJECT" value="REJECT" />
            <el-radio-button label="DROP" value="DROP" />
          </el-radio-group>
        </el-form-item>
        <el-form-item label="位置" prop="location">
          <el-radio-group v-model="form.location">
            <el-radio-button label="置尾" value="bottom" />
            <el-radio-button label="置顶" value="top" />
          </el-radio-group>
        </el-form-item>
      </el-form>
      <template #footer>
        <span>
          <el-button @click="visible = false">取 消</el-button>
          <el-button type="primary" @click="addOrEditAccessControlData">{{
            isAddStr === 'add' ? '新 建' : '确 定'
          }}</el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, watch, reactive, onUnmounted } from 'vue';
import { setObjectValue, verifyIP } from '@/utils/common';
import {
  addAccessControlByVPCApi,
  editAccessControlByVPCApi,
  getPortByVPCApi,
} from '@/api/topo/vpc';
import { ElMessage } from 'element-plus';
import { emitter } from '@/utils/bus';

const emit = defineEmits(['updateData']);
// 表单
const isAddStr = ref('');
const visible = ref(false);
const formRef = ref(null);
const form = reactive({
  s_addr: '0.0.0.0/0',
  d_addr: '0.0.0.0/0',
  protocol: 'all',
  d_port: '',
  in_eth: '*',
  out_eth: '*',
  action: 'ACCEPT',
  location: 'bottom',
});

// 接口列表
const portList = ref([]);

/**
 * 校验IP/掩码格式
 * @param rule
 * @param value
 * @param callback
 * @returns {*}
 */
const validateIP = (rule, value, callback) => {
  if (!value) return callback('IP地址/掩码不能为空');

  const [ip, mask] = value.split('/');
  if (!verifyIP(ip)) return callback('请输入合法IP地址/掩码，格式： 0.0.0.0/0');

  const masks = /^(?:[0-9]|[12]\d|3[0-2])$/;
  if (!masks.test(mask)) {
    return callback('请输入合法IP地址/掩码，掩码范围0-32');
  }
  return callback();
};

// 校验规则
let rules = {
  s_addr: [{ validator: validateIP, required: true, trigger: 'blur' }],
  d_addr: [{ validator: validateIP, required: true, trigger: 'blur' }],
};

/**
 * 确认添加访问控制
 */
const addOrEditAccessControlData = () => {
  formRef.value?.validate(async valid => {
    if (valid) {
      if (isAddStr.value === 'add') {
        addAccessControlByVPCApi(vpcID.value, form).then(res => {
          if (!(res instanceof Error)) {
            ElMessage.success('新建成功');
            visible.value = false;
            emit('updateData');
          }
        });
      } else {
        editAccessControlByVPCApi(vpcID.value, editObj.position, form, {}).then(
          res => {
            if (!(res instanceof Error)) {
              ElMessage.success('编辑成功');
              visible.value = false;
              emit('updateData');
            }
          },
        );
      }
    }
  });
};

/**
 * 获取接口列表
 */
const getPortList = () => {
  getPortByVPCApi(vpcID.value).then(res => {
    if (!(res instanceof Error)) {
      // 过滤未生成数据
      if (res.data?.length > 0) {
        portList.value = res.data.filter(item => item.generate);
      }
    }
  });
};

/**
 * 切换协议
 */
const protocolChange = () => {
  form.d_port = '';
};

// 编辑对象
let editObj = {};

// vpcID
const vpcID = ref(null);
const addOrEditAccessControlFunc = item => {
  visible.value = true;

  if (item.editObj) {
    isAddStr.value = 'edit';
    editObj = item.editObj;
    setObjectValue(form, item.editObj);
  } else {
    isAddStr.value = 'add';
  }

  vpcID.value = item.vpcID;
};

emitter.on('addOrEditAccessControl', addOrEditAccessControlFunc);

watch(
  visible,
  () => {
    if (!visible.value) {
      form.s_addr = '0.0.0.0/0';
      form.d_addr = '0.0.0.0/0';
      form.protocol = 'all';
      form.in_eth = '*';
      form.out_eth = '*';
      form.action = 'ACCEPT';
      form.location = 'bottom';
    } else {
      getPortList();
    }
  },
  { immediate: false },
);

onUnmounted(() => {
  emitter.off('addOrEditAccessControl', addOrEditAccessControlFunc);
});
</script>
<style lang="scss" scoped>
:deep(.add-vpc-access-dialog) {
  width: 560px;
  .el-form {
    max-width: 460px;
    .el-form-item__label {
      width: 100px;
    }

    .d-port {
      width: 140px;
      margin-right: 20px;
    }
  }
}
</style>
